#!/usr/bin/env ruby

require 'rubygems'
require 'faster_csv'
require 'gosim'

require 'benchmark'

class Logger #:nodoc:
  @@sim = GoSim::Simulation.instance

  private
  alias old_format_message format_message

  def format_message(severity, timestamp, progname, msg)
    "[#{@@sim.time}] #{msg}\n"
  end
end

module PeerCafe
  # TODO: Put in config.yml
  TOPICS_PER_CLIENT = 1
  NUM_CLIENTS = 30

  SIM_RUN_TIME = 200

  BASE_DIR = File.expand_path(File.dirname(__FILE__))

  class Base
    class << self
      def pc_dir(*args)
        File.join(BASE_DIR, args)
      end
    end
  end

  require 'lib/client'

  class Simulation
    include Singleton

    def initialize
      # Create the simulation
      @sim = GoSim::Simulation.instance

      # Configure logging
      #sim.log.level = Logger::DEBUG

      reset
    end

    def reset
      # Create Master Peer
      master_peer = MasterPeer.new

      # Read in the profiles -- (x,y) points
      profiles = []
      FasterCSV.foreach(Base.pc_dir("data/clusters.csv"), :converters => :float) do |row|
        profiles << row
      end

      # Build clients using random sets of profiles for each client.
      srand(10)
      clients = []
      NUM_CLIENTS.times do
        client_profiles = []
        TOPICS_PER_CLIENT.times do
          client_profiles << profiles.delete_at(rand(profiles.size))
        end

        clients << Client.new(client_profiles, master_peer.nid)
      end
    end

    def run
      puts "Beginning simulation...\n"
      puts "Simulation Runtime Statistics: \n\n"
      Benchmark.bm do |stat|
        stat.report { @sim.run(SIM_RUN_TIME) }
      end
    end
  end
end

require 'English'

if __FILE__ == $PROGRAM_NAME
  sim = PeerCafe::Simulation.instance
  sim.run
else
  require 'lib/visualizer'
  sim = PeerCafe::Simulation.instance
end
